package com.dlut.txy.designpattern.schedule.executor.impl;

import com.dlut.txy.designpattern.schedule.executor.ScheduleExecutor;
import com.dlut.txy.designpattern.schedule.task.ScheduleTask;
import com.dlut.txy.designpattern.schedule.task.TaskStatus;
import com.dlut.txy.designpattern.schedule.taskunit.TaskUnit;
import com.dlut.txy.designpattern.schedule.taskunit.impl.ThreadTaskUnit;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

@Slf4j
public class ThreadScheduleExecutor extends ScheduleExecutor {

    public static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().availableProcessors(),
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>());

    @Override
    public ScheduleExecutor addTask(ScheduleTask scheduleTask, int scheduleMills) {
        ThreadTaskUnit threadTaskUnit = new ThreadTaskUnit();
        threadTaskUnit.setScheduleTask(scheduleTask);
        threadTaskUnit.setScheduleMills(scheduleMills);
        threadTaskUnit.setStatus(TaskStatus.READY);
        super.taskMap.put(scheduleTask.getTaskId(), threadTaskUnit);
        return this;
    }

    @Override
    public void runTask(String taskId) {
        ThreadTaskUnit taskUnit = (ThreadTaskUnit) super.taskMap.get(taskId);

        if(taskUnit==null) {
            log.error("任务不存在");
            return;
        }
        if(taskUnit.getStatus() == TaskStatus.RUNNING) {
            log.error("已经在运行了不要重复执行");
            return;
        }
        if(taskUnit.getStatus() == TaskStatus.STOP) {
            log.error("任务已停止");
            return ;
        }
        taskUnit.setStatus(TaskStatus.RUNNING);
        EXECUTOR_SERVICE.submit(new Runnable() {
            @Override
            public void run() {
                ((ThreadTaskUnit) taskUnit).setCurThread(Thread.currentThread());
                while (taskUnit.getStatus() == TaskStatus.RUNNING) {
                    try {
                        Thread.sleep(taskUnit.getScheduleMills());
                    } catch (InterruptedException e) {
                        log.info("当前任务被中断");
                        stopTask(taskId);
                        break;
                    }
                    Object result = taskUnit.getScheduleTask().execute();
                    log.info("定时器执行 taskId={} 结果={}", taskId, result);
                }
                stopTask(taskId);
            }
        });

    }

}
